package da.metricscraft.client.frames.layers;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map.Entry;

import javax.imageio.ImageIO;

import da.metricscraft.client.frames.GraphicsPanel;
import da.metricscraft.client.threads.SpatialXMLLoader;
import da.metricscraft.client.threads.SpatialXMLLoader.LocationStruct;
import da.metricscraft.client.threads.SpatialXMLLoader.MoveActions;
import da.metricscraft.client.tools.Compressor;

public class SpatialPlayerLayer extends Layer<HashMap<String, ArrayList<SpatialXMLLoader.LocationStruct>>> {
	private static HashMap<MoveActions, SpatialPlayerLayer> singleton = new HashMap<SpatialXMLLoader.MoveActions, SpatialPlayerLayer>();
	private HashMap<Point, Integer> playerActionsPerPoint;
	private ArrayList<String> activePlayers;
	private int maxMines = 0;
	private boolean isAvailable = false;
	private BufferedImage gradient;
	private MoveActions action;
	private boolean runOnce = false;
	public static SpatialPlayerLayer getInstance(MoveActions action){
		return singleton.get(action);
	}
	public SpatialPlayerLayer(String name, Graphics g, Point size, MoveActions action) {
		super(name, g, size);
		
		singleton.put(action, this);
		this.action = action;
		playerActionsPerPoint = new HashMap<Point, Integer>();
		activePlayers = new ArrayList<String>();
		java.net.URL imgURL = getClass().getClassLoader().getResource("da/metricscraft/client/icons/colors.png");
		try {
			gradient = ImageIO.read(imgURL);
		} catch (IOException e) {
			e.printStackTrace();
		}
		// TODO Auto-generated constructor stub
	}
	public boolean getIsAvailable(){
		return isAvailable;
	}
	public void showPlayer(String player){
		if (!activePlayers.contains(player)){
			activePlayers.add(player);
			update(true);
		}
	}
	public void hidePlayer(String player){
		if (activePlayers.contains(player)){
			activePlayers.remove(player);
			update(true);
		}
	}
	@Override
	public void update(boolean draw) {
		// TODO Auto-generated method stub
		if (data != null){
			maxMines = 0;
			playerActionsPerPoint = new HashMap<Point, Integer>();
			int[] blocksize = GraphicsPanel.BLOCKSIZE;
//			long heapSize = Runtime.getRuntime().totalMemory()/1024;
//			long heapMaxSize = Runtime.getRuntime().maxMemory()/1024;
//			long heapFreeSize = Runtime.getRuntime().freeMemory()/1024;
//			System.out.println("Updating playerlayer - size: " + heapSize/1024 + " | max: " + heapMaxSize/1024 + " | free: " + heapFreeSize/1024);
			Graphics g = null;
			if (draw){
				layerImage = new BufferedImage((int)size.getX(), (int)size.getY(), BufferedImage.TYPE_INT_ARGB);
				 g = layerImage.getGraphics();
			}

			int[] posMod = { GraphicsPanel.getInstance().getLowest().x, GraphicsPanel.getInstance().getLowest().y};
			for (Entry<String, ArrayList<SpatialXMLLoader.LocationStruct>> m : data.entrySet()){
				if (!runOnce) activePlayers.add(m.getKey());
				if (!activePlayers.contains(m.getKey())) continue;
//				System.out.println("[SpatialPlayerLayer][update] Player loaded: " + m.getKey());
				ArrayList<SpatialXMLLoader.LocationStruct> positions = m.getValue();
				
				Collections.sort(positions);
				
				for(LocationStruct entry : positions){
//					System.out.println("[SpatialPlayerLayer][update] LocationStruct: " + entry.getAction().name() + " | Player: " + m.getKey());
					if (entry.getAction() == action){
						isAvailable = true;
						Point p = entry.getPosition();
						int value = 1;
						if (playerActionsPerPoint.containsKey(p)){
							value = 1 + playerActionsPerPoint.get(p);
						}
						if (value > maxMines){
							maxMines = value;
							System.out.println("maxmines per point: " + maxMines + " | on point: " + p.toString());
						}
						if (draw){
							g.setColor(new Color(0x00, 0x00, 0x00, 0x00));
							g.fillRect(blocksize[0] * (p.x - posMod[0]), blocksize[1] * (p.y - posMod[1]), blocksize[0], blocksize[1]);
							playerActionsPerPoint.put(p, value);
						}
					}
				}
			}
			if (draw){
				for(Entry<Point, Integer> entry : playerActionsPerPoint.entrySet()){
					Point p = entry.getKey();
					Color c = new Color(gradient.getRGB(0, entry.getValue() * gradient.getHeight()/maxMines - 1));
					
					g.setColor(new Color(c.getRed(), c.getGreen(), c.getBlue(), entry.getValue() * 0x99 /maxMines + 0x66));
					
					g.fillRect(blocksize[0] * (p.x - posMod[0]), blocksize[1] * (p.y - posMod[1]), blocksize[0], blocksize[1]);
					
				}
//				byte[] buff = Compressor.toByteArray(layerImage, 0.1f);
//				layerImage = Compressor.read(buff);
			}
			runOnce = true;
			GraphicsPanel.getInstance().repaint();
		}
	}

}
